package com.testing.soap;

import java.util.*;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import org.apache.axis2.context.NamedValue;

import com.jayway.jsonpath.JsonPath;
import com.testing.utils.LoggerConfig;
import com.testing.utils.ExcelWriter;

public class SoapInterControl {

    public SoapInterKeyWord client;

    public Map<String, String> paramMap;

    //加入成员变量，方便在每一行用例调用时，统一操作的行数、返回结果的断言、excel的写入。
    public String tmpResponse;

    public int line = 0; // 成员变量行数，用于在用例执行时保持执行行和写入行一致

    public ExcelWriter outExcel;

    public SoapInterControl(String casePath, String resultPath) {
        client = new SoapInterKeyWord();
        paramMap = new HashMap<String, String>();
        outExcel = new ExcelWriter(casePath, resultPath);
    }

    public SoapInterControl(ExcelWriter excel) {
        client = new SoapInterKeyWord();
        paramMap = new HashMap<String, String>();
        outExcel = excel;
    }

    public void createCon(String wsdlUrl) {
        try {
            client.createCon(wsdlUrl);
            outExcel.writeCell(line, 11, "PASS");
            LoggerConfig.LOGGER.info("基于wsdl文档地址建立连接");
        } catch (Exception e) {
            outExcel.writeFailCell(line, 11, "FAIL");
            LoggerConfig.LOGGER.error("连接建立失败，请检查wsdl文档");
            LoggerConfig.LOGGER.error(e, e.fillInStackTrace());
        }
    }

    public String testSoap(String targetNS, String interName, String paramString) {
        String response = null;
        try {
            String realParam = toParam(paramString);
            response = client.doSoap(targetNS, interName, realParam);
            tmpResponse = response;
            outExcel.writeCell(line, 12, tmpResponse);
            return response;
        } catch (Exception e) {
            LoggerConfig.LOGGER.error("post方法发送失败，请检查");
            LoggerConfig.LOGGER.error(e, e.fillInStackTrace());
            outExcel.writeFailCell(line, 11, "FAIL");
            outExcel.writeFailCell(line, 12, "post方法发送失败，请检查log");
            return response;
        }
    }

    public void addHeader(String originJson) {
        List<NamedValue> headers = new ArrayList<NamedValue>();
        String headerJson = toParam(originJson);
        try {
			JSONObject jsonObject = JSONObject.parseObject(headerJson);
			Set<String> set = jsonObject.keySet();
			for (String key:set) {
				NamedValue h = new NamedValue(key, jsonObject.get(key).toString());
				headers.add(h);
			}
            outExcel.writeCell(line, 11, "PASS");
        } catch (JSONException e) {
			LoggerConfig.LOGGER.error("头域参数格式错误，请检查");
			LoggerConfig.LOGGER.error(e, e.fillInStackTrace());
            outExcel.writeFailCell(line, 11, "FAIL");
        }
        client.addHeader(headers);
    }

    public void clearHeader() {
        try {
            client.clearHeader();
            outExcel.writeCell(line, 11, "PASS");
        } catch (Exception e) {
            outExcel.writeFailCell(line, 11, "FAIL");
        }
    }

    public void saveParam(String key, String jsonPath) {
        String value;
        try {
            value = JsonPath.read(tmpResponse, jsonPath).toString();
            paramMap.put(key, value);
            outExcel.writeCell(line, 11, "PASS");
        } catch (Exception e) {
			LoggerConfig.LOGGER.error("保存参数失败");
			LoggerConfig.LOGGER.error(e, e.fillInStackTrace());
            outExcel.writeCell(line, 11, "FAIL");
        }
    }

    public String toParam(String origin) {
        String param = origin;
        for (String key : paramMap.keySet()) {
            param = param.replaceAll("\\{" + key + "\\}", paramMap.get(key));
        }
        return param;
    }

    public void assertSame(String jsonPath, String expect) {
        try {
            String actual = JsonPath.read(tmpResponse, jsonPath).toString();
            if (actual != null && actual.equals(expect)) {
				LoggerConfig.LOGGER.info("测试通过！");
                outExcel.writeCell(line, 11, "PASS");
            } else {
				LoggerConfig.LOGGER.info("测试失败！");
                outExcel.writeFailCell(line, 11, "FAIL");
            }
        } catch (Exception e) {
			LoggerConfig.LOGGER.error("解析失败，请检查jsonPath表达式");
			LoggerConfig.LOGGER.error(e, e.fillInStackTrace());
            outExcel.writeFailCell(line, 11, "FAIL");
        }
    }

    public void assertContains(String jsonPath, String expect) {
        try {
            String actual = JsonPath.read(tmpResponse, jsonPath).toString();
            if (actual != null && actual.contains(expect)) {
				LoggerConfig.LOGGER.info("测试通过！");
                outExcel.writeCell(line, 11, "PASS");
            } else {
				LoggerConfig.LOGGER.info("测试失败！");
                outExcel.writeFailCell(line, 11, "FAIL");
            }
        } catch (Exception e) {
			LoggerConfig.LOGGER.error("解析失败，请检查jsonPath表达式");
			LoggerConfig.LOGGER.error(e, e.fillInStackTrace());
            outExcel.writeFailCell(line, 11, "FAIL");
        }
    }
}
